package com.example.mybatisplusproject.util;

import com.example.mybatisplusproject.dto.JsonResult;
import com.example.mybatisplusproject.entity.User;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.type.CollectionType;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.google.common.collect.Lists;

import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.util.List;

/**
 * JsonUtils
 * @author zls
 * @date 2021/12/19 3:56 下午
 */
public class JsonUtils {

    private static final ObjectMapper OBJECT_MAPPER = new ObjectMapper();

    static {

        // 对象的所有字段全部列入，还是其他的选项，可以忽略null等
        OBJECT_MAPPER.setSerializationInclusion(JsonInclude.Include.ALWAYS);
        // 设置Date类型的序列化及反序列化格式
        OBJECT_MAPPER.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
        // 忽略空Bean转json的错误
        OBJECT_MAPPER.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
        // 忽略未知属性，防止json字符串中存在，java对象中不存在对应属性的情况出现错误
        OBJECT_MAPPER.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        // 注册一个时间序列化及反序列化的处理模块，用于解决jdk8中localDateTime等的序列化问题
        OBJECT_MAPPER.registerModule(new JavaTimeModule());
    }

    public static String toJsonString(Object obj) {
        try {
            return OBJECT_MAPPER.writeValueAsString(obj);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static <T> T parseObject(String json, Class<T> clazz) {
        try {
            return OBJECT_MAPPER.readValue(json, clazz);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static <T> T parseObject(String json, TypeReference<T> type) {
        try {
            return OBJECT_MAPPER.readValue(json, type);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static <T> List<T> parseList(String json, Class<T> clazz) {
        try {
            JavaType javaType = OBJECT_MAPPER.getTypeFactory().constructParametricType(List.class, clazz);
            return OBJECT_MAPPER.readValue(json, javaType);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static <T> List<T> parseList(String json, TypeReference<T> type) {
        try {
            CollectionType collectionType = OBJECT_MAPPER.getTypeFactory().constructCollectionType(List.class, OBJECT_MAPPER.getTypeFactory().constructType(type));
            return OBJECT_MAPPER.readValue(json, collectionType);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        return null;
    }

    public static void main(String[] args) {
        User user = new User("张力升", 19);
        user.setCreateTime(LocalDateTime.now());
        String json = JsonUtils.toJsonString(user);
        User user1 = JsonUtils.parseObject(json, User.class);
        List<User> users = Lists.newArrayList(user, user1);
        String s1 = JsonUtils.toJsonString(users);
        List<User> users1 = JsonUtils.parseList(s1, User.class);
        System.err.println(users1);
        System.err.println(user1);
        JsonResult<String> jsonResult = new JsonResult<>();
        jsonResult.setCode("123");
        jsonResult.setMsg("success");
        jsonResult.setData("这是 data");
        String s = JsonUtils.toJsonString(jsonResult);
        JsonResult<String> object = JsonUtils.parseObject(s, new TypeReference<JsonResult<String>>() {
        });
        System.err.println(s);
        System.err.println(object);
        List<JsonResult<String>> list = Lists.newArrayList(jsonResult);
        String listStr = JsonUtils.toJsonString(list);
        List<JsonResult<String>> jsonResults = JsonUtils.parseList(listStr, new TypeReference<JsonResult<String>>() {
        });
        System.err.println(jsonResults);
    }
}
